package com.slofzx.nuoda.evaluation.project.compont;

import com.slofzx.nuoda.common.config.Type;
import com.slofzx.nuoda.common.dto.CompanyDTO;
import com.slofzx.nuoda.common.dto.DictDTO;
import com.slofzx.nuoda.common.dto.DictValueDTO;
import com.slofzx.nuoda.common.enums.CommonResultEnum;
import com.slofzx.nuoda.common.exception.ServiceException;
import com.slofzx.nuoda.common.feign.DictClient;
import com.slofzx.nuoda.common.feign.DictValueClient;
import com.slofzx.nuoda.common.feign.OfficeClient;
import com.slofzx.nuoda.common.vo.AjaxResultVO;
import com.slofzx.nuoda.common.vo.CompanyVO;
import com.slofzx.nuoda.common.vo.DictVO;
import com.slofzx.nuoda.common.vo.DictValueVO;
import com.slofzx.nuoda.evaluation.project.enums.ProductTypeEnum;
import com.slofzx.nuoda.evaluation.project.service.BatchCommonDataService;
import com.slofzx.nuoda.evaluation.project.service.ProjectInfoService;
import com.slofzx.nuoda.evaluation.project.service.ProjectYearDataService;
import com.slofzx.nuoda.evaluation.project.service.impl.BatchInfoServiceImpl;
import com.slofzx.nuoda.evaluation.project.util.BusiUtil;
import com.slofzx.nuoda.excel.service.ExcelService;
import com.slofzx.nuoda.excel.vo.ExcelPreviewDataVO;
import com.slofzx.nuoda.excel.vo.SheetConfigVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.Resource;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;

public abstract class AbstractExcelComponent {
    @Autowired
    protected BatchCommonDataService batchCommonDataService;
    @Autowired
    protected ProjectInfoService projectInfoService;
    @Resource
    protected ExcelService excelService;
    @Autowired
    protected OfficeClient officeClient;
    @Autowired
    protected DictValueClient dictValueClient;
    @Autowired
    protected ProjectYearDataService projectYearDataService;
    protected static Map<String, String> COMPANY_MAP = new HashMap<>();
    protected static Map<String, String> OIL_FILED_MAP = new HashMap<>();
    protected static Map<String, String> OIL_FILED_NAME_MAP = new HashMap<>();
    protected static final String GAS_TEMPLATE = "/template/gasTemplate.xlsx";
    protected static final String OIL_TEMPLATE = "/template/oilTemplate.xlsx";
    protected static final String PLAN_TEMPLATE = "/template/planTemplate.xlsx";
    protected static final String GAS_PLAN_TEMPLATE = "/template/gasPlanTemplate.xlsx";
    protected static final String COL_STR = "col";
    protected  ByteArrayOutputStream byteArrayOutputStream=null;

    protected Map<String, String> getFieldPositionMap(SheetConfigVO sheetConfigVO) {
        //字段位置信息 字段->位置
        Map<String, String> fieldPositionMap = new HashMap<>();
        List<Map<String, String>> rowDataList = sheetConfigVO.getDataList();
        if (rowDataList == null) {
            throw new ServiceException(CommonResultEnum.FILE_READERROR, "上传文件数据不能为空", null);
        }
        // 解析模板坐标位置
        for (Integer rowIndex = 0; rowIndex < rowDataList.size(); rowIndex++) {
            Map<String, String> rowData = rowDataList.get(rowIndex);
            if (rowData == null) {
                continue;
            }
            for (Map.Entry<String, String> cellEntry : rowData.entrySet()) {
                String value = cellEntry.getValue();
                if (value == null) {
                    continue;
                }
                value = value.trim();
                if (value.startsWith("{") && value.endsWith("}")) {
                    String fieldName = value.replaceAll("\\{\\.", "")
                            .replaceAll("\\{", "").replaceAll("\\}", "");
                    String positionKey = BusiUtil.generateBusiKey(rowIndex.toString(), cellEntry.getKey());
                    fieldPositionMap.put(fieldName, positionKey);
                }
            }
        }
        return fieldPositionMap;
    }


    /**
     * 获取组织机构ID
     *
     * @param buildOffice
     * @return
     */
    protected String getCompanyId(String buildOffice) {
        if (MapUtils.isNotEmpty(COMPANY_MAP)) {
            return COMPANY_MAP.get(buildOffice);
        }
        AjaxResultVO<List<CompanyVO>> companyAjax = officeClient.queryListInner(new CompanyDTO());
        List<CompanyVO> companyVOList = companyAjax.getData();
        if (CollectionUtils.isNotEmpty(companyVOList)) {
            COMPANY_MAP = companyVOList.stream().collect(Collectors.toMap(CompanyVO::getShortName, CompanyVO::getId, (v1, v2) -> v1));
            return COMPANY_MAP.get(buildOffice);
        }
        return null;
    }

    protected String getOilGasFieldId(String oilGasField) {
        if (MapUtils.isNotEmpty(OIL_FILED_NAME_MAP)) {
            return OIL_FILED_NAME_MAP.get(oilGasField);
        }
        final DictValueDTO dto = new DictValueDTO();
        dto.setDictId("oil-field");
        AjaxResultVO<List<DictValueVO>> oilGasFieldAjax = dictValueClient.queryList(dto);
        List<DictValueVO> companyVOList = oilGasFieldAjax.getData();
        if (CollectionUtils.isNotEmpty(companyVOList)) {
            OIL_FILED_NAME_MAP = companyVOList.stream().collect(Collectors.toMap(DictValueVO::getName, DictValueVO::getCode, (v1, v2) -> v1));
            return OIL_FILED_NAME_MAP.get(oilGasField);
        }
        return null;
    }

//    protected String getTemplatePath(String productType) {
//        String templatePath = OIL_TEMPLATE;
//        if (ProductTypeEnum.GAS.getId().equals(productType)) {
//            templatePath = GAS_TEMPLATE;
//        }
//        return templatePath;
//    }

    protected String convertEnumToName(Object fieldValue, Class<? extends Type> oilClazz,
                                     Class<? extends Type> gasClazz, ProductTypeEnum productType) {
        if (productType == ProductTypeEnum.OIL) {
            return getEnumName((String) fieldValue, oilClazz);
        } else {
            return getEnumName((String) fieldValue, gasClazz);
        }
    }

    protected String getEnumName(String fieldValue, Class<? extends Type> clazz) {
        final Type enumById = BusiUtil.getEnumById(fieldValue, clazz);
        if (Objects.nonNull(enumById)) {
            return enumById.getName();
        }
        return null;
    }
    /**
     * 获取模版数据
     *
     * @param
     * @return
     */
    protected ExcelPreviewDataVO getExcelPreviewData(String templatePath,boolean isCopy) {
        COMPANY_MAP = new HashMap<>();
        OIL_FILED_MAP = new HashMap<>();
        //解析上传文件数据，获取字段值
        ExcelPreviewDataVO templateFileData = null;
        try (InputStream inputStream = BatchInfoServiceImpl.class.getResourceAsStream(templatePath)) {
            if (isCopy) {
                byteArrayOutputStream = cloneInputStream(inputStream);
                // 复制模板文件
                templateFileData = excelService.previewDownloadWorkbook(byteArrayOutputStream.toByteArray());
            } else {
                // 复制模板文件
                templateFileData = excelService.previewDownloadWorkbook(inputStream);
            }


        } catch (Exception e) {
            throw new ServiceException(CommonResultEnum.FILE_READERROR, "文件模板读取失败", e.getMessage());
        }
        return templateFileData;
    }

    protected Integer getColIndex(String position) {
        String[] split = position.split(BusiUtil.DELIMITER);
        String colStr = split[1];
        String colIndexStr =  colStr.replace(COL_STR, StringUtils.EMPTY);
        final Integer colIndex = Integer.valueOf(colIndexStr);
        return colIndex;
    }

    private static ByteArrayOutputStream cloneInputStream(InputStream input) {
        try {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            byte[] buff = new byte[100];
            int rc = 0;
            while ((rc = input.read(buff, 0, 100)) > 0) {
                byteArrayOutputStream.write(buff, 0, rc);
            }
            return byteArrayOutputStream;

        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    protected Integer getRowIndex(Map<String, String> fieldPositionMap,String filed) {
        final String position = fieldPositionMap.get(filed);
        String[] split = position.split(BusiUtil.DELIMITER);
        String rowIndexStr = split[0];
        return Integer.valueOf(rowIndexStr) + 1;
    }
}
